// Learn cc.Class:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/class.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/class.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/life-cycle-callbacks.html


function Board(size) {
    this.size = size;
    this.grid = this.init();
}
Board.prototype = {
    init() {  // 形成一个空矩阵
        var grid = [];
        for(var i = 0; i < this.size; i++) {
            grid[i] = [];
            for(var j = 0; j < this.size; j++) {
                grid[i].push("");
            }
        }
        return grid;
    },
    usefulCell() { // 记录为空的格子
        var cells = [];
        for(var i = 0; i < this.size; i++)
            for(var j = 0; j < this.size; j++) {
                if(this.grid[i][j] == "") {  // 若可用则记录坐标
                    cells.push({
                        x: i,
                        y: j
                    });
                }
            }
        return cells;
    },
    selectCell() { // 从可填充格子中随机选一个
        var cells = this.usefulCell();
        if(cells.length) {
            return cells[Math.floor(Math.random()*cells.length)];
        }
    },
    cellEmpty() {  // 可用格子是否为空，为空返回true
        return !this.usefulCell().length;
    }
};


function tools(size) {
    this.size = size;
    this.startData = 2; // 初始填充2个数据
    this.init();
}

tools.prototype ={
    init() { // 填充数据
        this.board = new Board(this.size);
        this.bproto = this.board.__proto__;
        this.setDataRandom(); // 随机填充
        this.startData = 1;
    },
    setDataRandom() {  // 随机填充
        for(var i = 0; i < this.startData; i++) {
            this.addRandomData();
        }
    },
    addRandomData() { //填充数据
        if(!this.board.cellEmpty()) {
            var value = Math.random() < 0.9 ? 2 : 4;
            var cell = this.board.selectCell();
            cell.val = value;
            this.update(cell);
        }
    },
    update(cell) { // 更新数据
        this.board.grid[cell.x][cell.y] = cell.val;
    },
    move(dir) {
        // 0:上, 1:右, 2:下, 3:左
        var curList = this.formList(dir);

        var list = this.combine(curList);
        var result = [[],[],[],[]];

        for(var i = 0; i < this.size; i++)
            for(var j = 0; j < this.size; j++) {
                switch (dir) {
                    case 0:
                        result[i][j] = list[j][i];
                        break;
                    case 1:
                        result[i][j] = list[i][this.size-1-j];
                        break;
                    case 2:
                        result[i][j] = list[j][this.size-1-i];
                        break;
                    case 3:
                        result[i][j] = list[i][j];
                        break;
                }
            }
        this.board.grid = result;
        this.setDataRandom();

        return result;
    },
    formList(dir) {  // 根据滑动方向生成list的四个数组
        var list = [[], [], [], []];
        for(var i = 0; i < this.size; i++)
            for(var j = 0; j < this.size; j++) {
                switch(dir) {
                    case 0:
                        list[i].push(this.board.grid[j][i]);
                        break;
                    case 1:
                        list[i].push(this.board.grid[i][this.size-1-j]);
                        break;
                    case 2:
                        list[i].push(this.board.grid[this.size-1-j][i]);
                        break;
                    case 3:
                        list[i].push(this.board.grid[i][j]);
                        break;
                }
            }
        return list;
    },
    combine(list) { // 滑动时相同的合并
        for(var i = 0; i < list.length; i++)  // 数字靠边
            list[i] = this.changeItem(list[i]);

        for(var i = 0; i < this.size; i++) {
            for(var j = 1; j < this.size; j++) {
                if(list[i][j-1] == list[i][j] && list[i][j]!="") {
                    list[i][j-1] += list[i][j];
                    list[i][j] = "";
                }
            }
        }
        for (var i = 0; i < list.length; i++)  // 再次数字靠边
            list[i] = this.changeItem(list[i]);

        return list;
    },
    changeItem(item) {  // 将 ['', 2, '', 2] 改为 [2, 2, '', '']
        var cnt = 0;
        for(var i = 0; i < item.length; i++)
            if(item[i] != '')
                item[cnt++] = item[i];
        for(var j = cnt; j < item.length; j++)
            item[j] = "";
        return item;
    },
    isOver() {  // 游戏是否结束，结束条件：可用格子为空且所有格子上下左右值不等
        this.board.__proto__ = this.bproto;
        if (!this.board.cellEmpty()) {
            return false;
        } else {
            for (var i = 0; i < this.size; i++) // 左右不等
                for (var j = 1; j < this.size; j++) {
                    if (this.board.grid[i][j] == this.board.grid[i][j - 1])
                        return false;
                }
            for (var j = 0; j < this.size; j++)  // 上下不等
                for (var i = 1; i < this.size; i++) {
                    if (this.board.grid[i][j] == this.board.grid[i - 1][j])
                        return false;
                }
        }
        return true;
    }
};




cc.Class({
    extends: cc.Component,

    properties: {
        cells :{
            default:[],
            type:[cc.Label],
        },
		result:{
			default:null,
			type:cc.Label,
		},
		score:{
			default:0,
			type:cc.Integer,
		}
        // foo: {
        //     // ATTRIBUTES:
        //     default: null,        // The default value will be used only when the component attaching
        //                           // to a node for the first time
        //     type: cc.SpriteFrame, // optional, default is typeof default
        //     serializable: true,   // optional, default is true
        // },
        // bar: {
        //     get () {
        //         return this._bar;
        //     },
        //     set (value) {
        //         this._bar = value;
        //     }
        // },
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad: function () {
        this.cells.forEach(function (c) {
            c.string = ""
        })
        this.node.on(cc.Node.EventType.TOUCH_START,this.touchStart,this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE,this.touchMove,this);
        this.node.on(cc.Node.EventType.TOUCH_END,this.touchEnd,this);
        this.node.Ts = new tools(4);
		this.node.gameOver = this.gameOver;
		this.node.updateView = this.updateView;

    },

    start () {
    },
    score : 0,
    gameOver: function(target,t) {  // 游戏结束
        
        if (t.score >= 512) {
            t.result.string= '口令：我玩亚瑟贼溜';
        } else {
            t.result.string='哎呀，差点呢！';
        }
    },
    touchStartX: 0,
    touchStartY: 0,
    touchEndX: 0,
    touchEndY: 0,
	endMsg:"",
    touchStart: function(ev) { // 触摸开始坐标
        var touch = ev.getLocation();
        ev.target.touchStartX = touch.x;
        ev.target.touchStartY = touch.y;

    },
    touchMove: function(ev) { // 触摸最后移动时的坐标
        var touch = ev.getLocation();
        ev.target.touchEndX = touch.x;
        ev.target.touchEndY = touch.y;
    },
    touchEnd: function(ev) {
        var disX = ev.target.touchStartX - ev.target.touchEndX;
        var absdisX = Math.abs(disX);
        var disY = ev.target.touchStartY - ev.target.touchEndY;
        var absdisY = Math.abs(disY);

        if(ev.target.Ts.isOver()) { // 游戏是否结束
            ev.target.gameOver(ev.target,this);
        } else {
            if (Math.max(absdisX, absdisY) > 10) { // 确定是否在滑动
                
                var direction = absdisX > absdisY ? (disX < 0 ? 1 : 3) : (disY >0 ? 2 : 0);  // 确定移动方向
                var data = ev.target.Ts.move(direction);
                ev.target.updateView(data,ev,this);
            }
        }
    },
    updateView : function(data,ev,t){
        for(var i = 0; i < 4; i++)
            for(var j = 0; j < 4; j++) {
                if (data[i][j] != "" && data[i][j] > t.score)
                    t.score = data[i][j];
                t.cells[i*4+j].string = data[i][j] ;
        }
    }
});
